package com.iot.manager.network;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.iot.manager.utils.SharedPreferencesManager;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

public class WebSocketManager {
    private static final String TAG = "WebSocketManager";
    private static WebSocketManager instance;
    private WebSocket webSocket;
    private final OkHttpClient client;
    private final Context context;
    private List<DeviceStatusListener> statusListeners = new ArrayList<>();
    private List<DeviceDataListener> dataListeners = new ArrayList<>();
    private boolean isConnected = false;
    private static final String WS_URL = "ws://123.56.226.74:3001/ws";
    private boolean isReconnecting = false;
    private static final long RECONNECT_DELAY = 5000;

    public interface DeviceStatusListener {
        void onDeviceStatusChanged(String deviceId, String status, String lastHeartbeat);
    }

    public interface DeviceDataListener {
        void onDeviceDataUpdated(String deviceId, Double temperature, Double humidity);
    }

    public interface DeviceStatsListener {
        void onDeviceStatsUpdated(int totalDevices, int onlineDevices, int offlineDevices);
    }

    private List<DeviceStatsListener> statsListeners = new ArrayList<>();

    private WebSocketManager(Context context) {
        this.context = context.getApplicationContext();
        this.client = new OkHttpClient.Builder()
                .readTimeout(0, TimeUnit.MILLISECONDS)
                .pingInterval(30, TimeUnit.SECONDS)
                .build();
    }

    public static synchronized WebSocketManager getInstance(Context context) {
        if (instance == null) {
            instance = new WebSocketManager(context);
        }
        return instance;
    }

    public void connect(String token) {
        if (isConnected) {
            return;
        }

        Request request = new Request.Builder()
                .url(WS_URL + "?token=" + token)
                .build();

        webSocket = client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                Log.d(TAG, "WebSocket connected");
                isConnected = true;
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                Log.d(TAG, "Received message: " + text);
                handleMessage(text);
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                Log.d(TAG, "WebSocket closing: " + reason);
                isConnected = false;
                webSocket.close(1000, null);
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                Log.e(TAG, "WebSocket error: " + t.getMessage());
                isConnected = false;
                // 尝试重新连接
                reconnect();
            }
        });
    }

    private void reconnect() {
        if (isReconnecting) return;
        isReconnecting = true;
        
        // 使用主线程的Handler
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            String token = SharedPreferencesManager.getInstance(context).getToken();
            if (token != null) {
                connect(token);
            }
            isReconnecting = false;
        }, RECONNECT_DELAY);
    }

    public void disconnect() {
        if (webSocket != null) {
            webSocket.close(1000, "Disconnecting");
            webSocket = null;
        }
        isConnected = false;
    }

    public void addStatusListener(DeviceStatusListener listener) {
        if (!statusListeners.contains(listener)) {
            statusListeners.add(listener);
        }
    }

    public void removeStatusListener(DeviceStatusListener listener) {
        statusListeners.remove(listener);
    }

    public void addDataListener(DeviceDataListener listener) {
        if (!dataListeners.contains(listener)) {
            dataListeners.add(listener);
        }
    }

    public void removeDataListener(DeviceDataListener listener) {
        dataListeners.remove(listener);
    }

    public void addStatsListener(DeviceStatsListener listener) {
        if (!statsListeners.contains(listener)) {
            statsListeners.add(listener);
        }
    }

    public void removeStatsListener(DeviceStatsListener listener) {
        statsListeners.remove(listener);
    }

    private void handleMessage(String message) {
        try {
            JSONObject json = new JSONObject(message);
            String type = json.getString("type");
            JSONObject data = json.getJSONObject("data");

            switch (type) {
                case "deviceUpdate":
                    // 处理设备统计信息
                    int totalDevices = data.getInt("totalDevices");
                    int onlineDevices = data.getInt("onlineDevices");
                    int offlineDevices = data.getInt("offlineDevices");
                    
                    // 使用主线程的Handler通知监听器
                    new Handler(Looper.getMainLooper()).post(() -> {
                        for (DeviceStatsListener listener : statsListeners) {
                            listener.onDeviceStatsUpdated(totalDevices, onlineDevices, offlineDevices);
                        }
                    });
                    
                    // 处理设备列表更新
                    JSONArray devices = data.getJSONArray("devices");
                    for (int i = 0; i < devices.length(); i++) {
                        JSONObject device = devices.getJSONObject(i);
                        String devId = device.getString("deviceId");
                        String devStatus = device.getString("status");
                        String lastHeartbeat = device.getString("lastHeartbeat");
                        
                        // 使用主线程的Handler通知监听器
                        new Handler(Looper.getMainLooper()).post(() -> {
                            for (DeviceStatusListener listener : statusListeners) {
                                listener.onDeviceStatusChanged(devId, devStatus, lastHeartbeat);
                            }
                        });
                        
                        // 如果有温度和湿度数据，也通知数据监听器
                        if (device.has("temperature") || device.has("humidity")) {
                            Double temp = device.has("temperature") ? device.getDouble("temperature") : null;
                            Double hum = device.has("humidity") ? device.getDouble("humidity") : null;
                            new Handler(Looper.getMainLooper()).post(() -> {
                                for (DeviceDataListener listener : dataListeners) {
                                    listener.onDeviceDataUpdated(devId, temp, hum);
                                }
                            });
                        }
                    }
                    break;

                case "device_status_broadcast":
                    String deviceId = data.getString("deviceId");
                    String status = data.getString("status");
                    String timestamp = data.getString("timestamp");
                    JSONObject metadata = data.getJSONObject("metadata");
                    String lastSeen = metadata.getString("lastSeen");
                    
                    // 使用主线程的Handler通知监听器
                    new Handler(Looper.getMainLooper()).post(() -> {
                        for (DeviceStatusListener listener : statusListeners) {
                            listener.onDeviceStatusChanged(deviceId, status, lastSeen);
                        }
                    });
                    break;

                case "device_data_update":
                    String dataDeviceId = data.getString("deviceId");
                    Double temperature = data.has("temperature") ? data.getDouble("temperature") : null;
                    Double humidity = data.has("humidity") ? data.getDouble("humidity") : null;
                    
                    // 使用主线程的Handler通知监听器
                    new Handler(Looper.getMainLooper()).post(() -> {
                        for (DeviceDataListener listener : dataListeners) {
                            listener.onDeviceDataUpdated(dataDeviceId, temperature, humidity);
                        }
                    });
                    break;
            }
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing WebSocket message", e);
        }
    }
} 